package com.joinway.framework.admin.core.service.file;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.joinway.framework.admin.core.bean.FileImportContext;
import com.joinway.framework.core.plugin.PluginAdaptor;
import com.joinway.framework.data.jdbc.repository.TableRepository;
import com.joinway.framework.extension.groovy.DomainUtils;
import com.joinway.framework.extension.groovy.GroovyUtils;


public abstract class AbstractFileProcessor extends PluginAdaptor implements FileProcessor {

	private final static Logger log = LoggerFactory.getLogger(AbstractFileProcessor.class);
			
	@Autowired protected TableRepository repository;
	
	/**
	 * 匈牙利命名法格式的表名
	 * @return 默认为空，使用框架默认类处理文件导入/导出。如果针对每个表使用不同的导入/导出逻辑，需要子类重写此方法。
	 */
	@Override
	public String getTargetTable(){
		return null;
	}

	protected FileImportContext imports(List<String> columns, List<List<String>> records, String table) throws Exception {
//		String batchId = UUID.randomUUID().toString();
		
		log.info("importing columns {} ", columns);
		
		beforeImports(columns, records, table);
		
		String tableName = DomainUtils.convertToDBName(table);
		
		List<String> importColumns = buildImportColumns(columns);
		
		int importedCount = 0;
		int ignoredCount = 0;
		
		for(int i = 0; i < records.size(); i++){
			List<String> row = buildImportRow(columns, records.get(i));
			
			if(canPersist(columns, row, table)){
				Object domain = GroovyUtils.createGroovyObject();
				
				for(int j = 0; j < importColumns.size(); j++){
					String columnName = importColumns.get(j);
					String fieldName = DomainUtils.convertToDomainFieldName(columnName);
					Object value = row.get(j);
					value = GroovyUtils.isTrue(value) ? value : null;
	//				domain.metaClass."$fieldName" = value ? value : null;
					GroovyUtils.addProperty(domain, fieldName, value);
				}
				
				repository.persist(tableName, domain);
				
				afterImportRow(columns, row, table, domain);
				
				importedCount++;
			}else{
				log.debug("ignored to persist row {}", row);
				ignoredCount++;
			}
		}
		
		FileImportContext context = afterImports(columns, records, table);
		
		if(context == null){
			context = new FileImportContext();
			
			context.setImportedCount(importedCount);
			context.setIgnoredCount(ignoredCount);
			context.setMessage("导入" + importedCount + "条记录");
		}
		
		return context;
	}

	/**
	 * 
	 * @param columnMap format is fieldName1,displayName1;fieldName2,displayName2;
	 * @return column map, key - display name; value - db column name
	 */
	protected Map<String, String> getColumnMap(String columnMap){
		Map<String, String> map = new HashMap<>();
		
		String[] parts = columnMap.split(";");
		
		for(String p : parts){
			String[] items = p.split(",");
			
			map.put(items[1], DomainUtils.convertToDBName(items[0]));
		}
		
		return map;
	}
	
//	protected void validate(List<String> importColumns) throws ValidationException {
//		for(String c : importColumns){
//			if(StringUtils.isBlank(c) || "null".equalsIgnoreCase(c)){
//				throw new ValidationException();
//			}
//		}
//	}
	
	protected List<String> buildImportColumns(List<String> columns) throws Exception {
		return columns;
	}
	
	protected List<String> buildImportRow(List<String> columns, List<String> row) throws Exception {
		return row;
	}
	
	protected boolean canPersist(List<String> columns, List<String> row, String table) throws Exception {
		return true;
	}
	
	protected String getExportTextValue(String columnName, int columnIndex, Object value){
		return value == null ? "" : StringUtils.trimToEmpty(String.valueOf(value));
	}

	protected String getImportTextValue(String columnName, int columnIndex, String value){
		String v = value == null ? "" : StringUtils.trimToEmpty(value);
		
		if(v.contains("E+")){
			try{
				v = new BigDecimal(v).toPlainString();
			}catch(Exception e){
				log.warn("can't convert " + v + " to number");
			}
		}
		
		return v;
	}
	
	protected void beforeImports(List<String> columns, List<List<String>> records, String table) throws Exception {
		
	}
	
	protected FileImportContext afterImports(List<String> columns, List<List<String>> records, String table) throws Exception {
		return null;
	}
	
	protected void afterImportRow(List<String> columns, List<String> records, String table, Object domain) throws Exception {
		
	}
	
	protected FileImportContext createDefaultFileImportContext(){
		FileImportContext context = new FileImportContext();
		
		context.setImportedCount(0);
		context.setIgnoredCount(0);
		context.setMessage("导入完毕");
		
		return context;
	}
}
